package com.example.beacondemo;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import org.altbeacon.beacon.AltBeacon;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.MonitorNotifier;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.simulator.BeaconSimulator;
import org.altbeacon.beacon.startup.BootstrapNotifier;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static com.example.beacondemo.BeaconService.bytesToHexString;

public class MainActivity extends Activity {

    public static final String TAG = "MainActivity";
    public static final String BEACON_ACTION = "com.example.beacondemo";
    private BeaconManager beaconManager = BeaconManager.getInstanceForApplication(MainActivity.this);
    private BeaconBroadcastReceiver beaconBroadcastReceiver;

    private ListView lvBeacons;
    private List<String> texts;
    private MyAdapter myAdapter;

    public static final String IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";
    public static final String UNKNOW_FORMAT = "m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25";

    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
    private BluetoothAdapter bluetoothAdapter;
    private Button btnBLEscan;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            if(this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_REQUEST_COARSE_LOCATION);
            }
        }
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();
        beaconBroadcastReceiver = new BeaconBroadcastReceiver();
        texts = new ArrayList<>();
        Intent intent = new Intent(MainActivity.this, BeaconService.class);
        startService(intent);

        lvBeacons = (ListView) findViewById(R.id.lv_beacons);
        btnBLEscan = findViewById(R.id.btn_blescan);
        myAdapter = new MyAdapter(this,R.layout.beacons_view,texts);
        lvBeacons.setAdapter(myAdapter);
        btnBLEscan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!isScaning) {
                    isScaning = true;
                    BLEscan();
                }
                else {
                    isScaning = false;
                    BLEstop();
                }
            }
        });
    }
    boolean isScaning = false;
    private Map<String,String> devices = new HashMap<>();

    public void BLEscan(){
        Toast.makeText(this,"start Scan...",Toast.LENGTH_SHORT);
        bluetoothAdapter.startLeScan(callback);

    }

    public void BLEstop(){
        Toast.makeText(this,"stop Scan...",Toast.LENGTH_SHORT);
        bluetoothAdapter.stopLeScan(callback);
    }

    BluetoothAdapter.LeScanCallback callback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            //Log.d("BLEscanDemo",device.getAddress()+", "+rssi+", ["+bytesToHexString(scanRecord)+"]");
            Log.d(TAG,device.getName()+": "+bytesToHexString(scanRecord));
            if(!devices.containsKey(device.getAddress())){
                devices.put(device.getAddress(),bytesToHexString(scanRecord));
                new AlertDialog.Builder(MainActivity.this)
                        .setTitle("Found ble")
                        .setMessage(device.getName()+": "+devices.get(device.getAddress()))
                        .show();
            }

        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(beaconBroadcastReceiver != null){
            unregisterReceiver(beaconBroadcastReceiver);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(beaconBroadcastReceiver,getBeaconIntentFilter());
    }

    @Override
    protected void onPause() {
        super.onPause();
        if(beaconBroadcastReceiver != null){
            unregisterReceiver(beaconBroadcastReceiver);
        }
    }


    class BeaconBroadcastReceiver extends BroadcastReceiver{

        Map<String,String> beacMap = new HashMap();
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BEACON_ACTION.equals(action)) {
                List<Beacon> beacons = intent.getParcelableArrayListExtra("beacon");
                Log.i(TAG, "onReceive: " + beacons.size());
                for (Beacon beacon : beacons) {

                    //获取 uuid，major，minor
                    String uuid = String.valueOf(beacon.getId1());
                    String major = String.valueOf(beacon.getId2());
                    String mMinor = String.valueOf(beacon.getId3());
                    int minor = Integer.parseInt(mMinor);
                    String address = beacon.getBluetoothAddress();
                    String text = "UUID: " +beacon.getId1() + "\r\n" +
                            "Major: "+beacon.getId2() + "\r\n" +
                            "Minor: "+beacon.getId3()  + "\r\n" +
                            "Address: " + beacon.getBluetoothAddress() + "\r\n" +
                            "TxPower: " + beacon.getTxPower()  + "\r\n" +
                            "Rssi: " + beacon.getRssi() + "\r\n" +
                            "RssiAvg:" + new BigDecimal(beacon.getRunningAverageRssi()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue() + "\r\n" +
                            "Distance: " + new BigDecimal(beacon.getDistance()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()+ "m";
                    beacMap.put(address,text);

                    Log.i(TAG, "onReceive: " + text);

                }
                texts.clear();
                for(String tt : beacMap.values()){

                    texts.add(tt);
                }
                for(String tt : texts){
                    Log.d("TEXT",tt);
                }
                //texts.add(UUID.randomUUID()+"");
                myAdapter.setTexts(texts);
                myAdapter.notifyDataSetChanged();
                Log.i(TAG, "onReceive: " + "**********************************");
            }
        }
    }
    IntentFilter getBeaconIntentFilter() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BEACON_ACTION);
        return intentFilter;
    }



    class MyAdapter extends ArrayAdapter {
        private List<String> texts;
        private Context context;

        public MyAdapter( Context context, int resource,  List<String> texts) {
            super(context, resource, texts);
            this.context = context;
            this.texts = texts;
        }

        public void setTexts(List<String> texts){
            this.texts = texts;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            //View view = LayoutInflater.from(getContext()).inflate(R.id.rl_lv,parent,null);
            View view = LayoutInflater.from(getContext()).inflate(R.layout.beacons_view,parent,false);
            TextView tv = (TextView) view.findViewById(R.id.tv_list);
            tv.setText(texts.get(position));
            return view;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case PERMISSION_REQUEST_COARSE_LOCATION:
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(this, "PERMISSION_GRANTED", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}
